/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Drawable;

import Base.Point;
import Base.Transform;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.util.ArrayList;

/**
 *
 * @author atxy2k
 */
public class Polygon {
    private ArrayList<Point> list = new ArrayList<>();
    private boolean asign = false, ready = true;
    private Point reference = new Point(0, 0);
    private int minX, maxX, minY,maxY, centerX, centerY;
    private float pixelSize;
    private boolean paintPoints = true;
    private boolean paint = true;
    private Transform t;
    /**
     * 
     * @param x X en coordenada real
     * @param y Y en coordenada real
     */
    public void add(float x, float y){
        if (!asign) {
            if (ready) {
                list.clear();
                list.add(new Point(x, y));
                ready = false;
            }else{
                if (closing(x, y)) {
                    x = list.get(0).getX();
                    y = list.get(0).getY();
                    list.add(new Point(x, y));
                    ready = true;
                }else{
                    list.add(new Point(x, y));
                }
            }
        }else{
            reference = new Point(x, y);
            asign = false;
        }
    }
    /**
     * 
     * @param g Representa el grafico donde se dibujara (Antes ejecute initVars)
     */
    public void paint(Graphics g){
        if (paint) {
            if (!list.isEmpty()) {
                if (paintPoints) {
                    g.drawRect(minX, minY, 6, 6);
                    g.setColor(Color.red);
                    g.drawRect(toFisicX(reference.getX())-3, toFisicY(reference.getY())-3, 6, 6);
                    g.setColor(Color.black);
                }
                if (list.size()>1) {
                    for (int i = 0; i < list.size()-1; i++) {
                        g.drawLine(toFisicX(list.get(i).getX()),  toFisicY(list.get(i).getY()),
                                   toFisicX(list.get(i+1).getX()),toFisicY(list.get(i+1).getY()));
                    }
                }
            }
        }
    }
    /**
     * 
     * @param centerX centro de X en un canvas
     * @param centerY centro de Y en un canvas
     * @param pixelSize obtenido de Math.max(rWidht/maxX, rHeight/maxY) 
     */
    public void initVars(int centerX, int centerY, float pixelSize){
        this.centerX = centerX;
        this.centerY = centerY;
        this.pixelSize = pixelSize;
        if (!list.isEmpty()) {
            minX = toFisicX(list.get(0).getX())-3;
            minY = toFisicY(list.get(0).getY())-3;
            maxX = toFisicX(list.get(0).getX())+3;
            maxY = toFisicY(list.get(0).getY())+3;
        }   
    }
    /**
     * 
     * @param evt evento del teclado
     */
    public void KeyEvent(KeyEvent evt){
        t = new Transform(list);
        int n = evt.getKeyCode();
        switch (n) {
            case KeyEvent.VK_NUMPAD5: asign = true;     break;
            case KeyEvent.VK_NUMPAD4: t.moveLeft();     break;
            case KeyEvent.VK_NUMPAD6: t.moveRight();    break;
            case KeyEvent.VK_NUMPAD8: t.moveUp();       break;
            case KeyEvent.VK_NUMPAD9: t.moveRightUp();  break;
            case KeyEvent.VK_NUMPAD1: t.moveLeftDown(); break;
            case KeyEvent.VK_NUMPAD2: t.moveDown();     break;
            case KeyEvent.VK_NUMPAD3: t.moveRightDown();break;
            case KeyEvent.VK_NUMPAD7: t.moveLeftUp();   break;
            case KeyEvent.VK_W: t.increment();          break;
            case KeyEvent.VK_S: t.decrement();          break;
            case KeyEvent.VK_A: t.rotationLeft();      break;
            case KeyEvent.VK_D: t.rotationRight();      break;
            case 107: t.increment(reference);            break;
            case KeyEvent.VK_SUBTRACT: t.decrement(reference);break;
            case KeyEvent.VK_RIGHT: t.rotationRight(reference);break;
            case KeyEvent.VK_LEFT: t.rotationLeft(reference);break;
            case KeyEvent.VK_Q: t.reflectionInX();break;
            case KeyEvent.VK_E: t.reflectionInY();break;
        }
    }
    /**
     * 
     * @param x Coordenada X del punto a evaluar
     * @param y Coordenada Y del punto a evaluar
     * @return True si el punto se encuentra dentro de minX,maxY, minY y maxY, si no False
     */
    private boolean closing(float x, float y){
        int x1 = toFisicX(x);
        int y1 = toFisicY(y);
        return x1>=minX && x1 <=maxX && y1>=minY && y1<=maxY ? true: false;
    }
    /**
     * 
     * @param x Coordenada x en real a transformar a fisica antes de dibujar
     * @return la coordenada X en fisica
     */
    private int toFisicX(float x){
        return Math.round(centerX+x/pixelSize);
    }
    /**
     * 
     * @param y Coordenada y en real a transformar
     * @return La coordenada transformada a fisica
     */
    private int toFisicY(float y){
        return Math.round(centerY-y/pixelSize);
    }
    
}
